package com.qijia.travel.app;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import com.qijia.travel.common.Constants;
import com.qijia.travel.common.SqlMappedId;
import com.qijia.travel.dao.BaseDAO;
import com.qijia.travel.dao.SingletonDaoFactory;
import com.qijia.travel.dao.TravelDbException;
import com.qijia.travel.domain.AgencyMission;
import com.qijia.travel.domain.Guide;
import com.qijia.travel.domain.PageResult;
import com.qijia.travel.domain.RewardProfit;
import com.qijia.travel.domain.TouristGroup;
import com.qijia.travel.domain.TouristGroupDetail;
import com.qijia.travel.domain.TouristGroupProfit;
import com.qijia.travel.domain.TouristGroupReward;
import com.qijia.travel.domain.TouristWorkDetail;
import com.qijia.travel.domain.example.ExampleFactory;
import com.qijia.travel.domain.example.StatisticsExample;
import com.qijia.travel.domain.example.TouristGroupDetailExample;
import com.qijia.travel.domain.example.TouristGroupExample;
import com.qijia.travel.domain.example.TouristGroupProfitExample;
import com.qijia.travel.domain.example.TouristGroupRewardExample;
import com.qijia.travel.domain.example.TouristWorkDetailExample;
import com.qijia.travel.helper.DateHelper;
import com.qijia.travel.helper.FileHelper;
import com.qijia.travel.helper.ObjectHelper;
import com.qijia.travel.helper.RandomNumberHelper;
import com.qijia.travel.vo.GuideVO;
import com.qijia.travel.vo.StatisticsVo;
import com.qijia.travel.vo.TouristDetailVo;

public class TouristManager {
	private BaseDAO baseDao;
	private GroupManager groupManager;
	private ProfitManager profitManager;
	private RewardManager rewardManager;
	private GuideManager guideManager;

	public TouristManager() {
		try {
			baseDao = SingletonDaoFactory.createDAO();
			groupManager = new GroupManager();
			profitManager = new ProfitManager();
			rewardManager = new RewardManager();
			guideManager = new GuideManager();
		} catch (TravelDbException e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("unchecked")
	public TouristWorkDetail getWorkDetailByDetaiId(int detailId)
			throws AppErrorException {
		TouristWorkDetailExample example = ExampleFactory
				.createTouristWorkDetailExample();
		example.setPageSize(1);
		example.createCriteria().andTouristGroupDetailIdEqualTo(detailId);

		try {
			List<TouristWorkDetail> details = (List<TouristWorkDetail>) baseDao
					.selectByExample(SqlMappedId.TOURIST_GROUP_DETAI + "."
							+ SqlMappedId.selectPageByExample, example);

			if (details != null && details.size() > 0) {
				return details.get(0);
			} else
				return null;
		} catch (TravelDbException e) {
			throw new AppErrorException("获取旅程信息失败! 请稍候重试!");
		}
	}

	public void createTourist(TouristDetailVo vo, HttpSession session)
			throws AppErrorException {
		if (null == vo)
			throw new AppErrorException("请输入旅游团详细信息!");

		TouristGroupDetail detail = null;
		TouristGroup group = null;
		TouristGroupProfit profit = null;
		TouristGroupReward reward = null;
		AgencyMission am = null;
		Guide guide = null;

		try {
			guide = new Guide();
			guide.setGuideId(vo.getGuideId());
			guide.setGuideName(vo.getGuideName());

			// 导游信息补全
			guide = guideManager.settingGuide(guide);
			vo.setGuideId(guide.getGuideId());
			vo.setGuideName(guide.getGuideName());

			detail = (TouristGroupDetail) ObjectHelper.objToObj(vo,
					TouristGroupDetail.class);
			group = (TouristGroup) ObjectHelper
					.objToObj(vo, TouristGroup.class);
			am = (AgencyMission) ObjectHelper.objToObj(vo, AgencyMission.class);

			Date startDate = null, endDate = null;
			if (null != vo.getStDate()) {
				try {
					startDate = DateHelper.parseToDate(vo.getStDate(),
							DateHelper.yyyyMMdd);
					if (null == vo.getEdDate())
						endDate = new Date();
					else
						endDate = DateHelper.parseToDate(vo.getEdDate(),
								DateHelper.yyyyMMdd);

					detail.setStartDt(startDate);
					detail.setContinuedDate(new Float(DateHelper
							.getDaysBetween(startDate, endDate)));
					detail.setEndDt(endDate);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		}

		int detailId = 0;
		try {// 先保存旅行团信息
			baseDao.getSqlMapClient().startTransaction();
			int groupId = groupManager.createAgencyMission(am);
			group.setAgencyMissionId(groupId);
			groupManager.createTouristGroup(group);

			detail.setTouristGroupSn(group.getTouristGroupSn());
			detailId = saveTouristDetail(detail);

			if (null != group.getTouristFile()
					&& group.getTouristFile().trim().length() > 0)
				FileHelper.CopyFileByChannel(group.getTouristFile(),
						Constants.FILE_SAVE_DIR + group.getTouristGroupSn()
								+ "_" + detailId);

			baseDao.getSqlMapClient().commitTransaction();
		} catch (SQLException e) {
			e.printStackTrace();
			// throw new AppErrorException("增加旅程信息失败! 请检查必填数据是否已填完整!");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				baseDao.getSqlMapClient().endTransaction();
			} catch (SQLException e) {
				e.printStackTrace();
				throw new AppErrorException("增加旅程信息失败! 请检查必填数据是否已填完整!");
			}
		}

		try {// 再保存旅行团创利和奖励信息
			profit = (TouristGroupProfit) ObjectHelper.objToObj(vo,
					TouristGroupProfit.class);
			profit.setTouristGroupDetailId(detailId);
			profit.setTouristGroupSn(group.getTouristGroupSn());
			profit.setGuideId(detail.getGuideId());
			profit.setGuideName(detail.getGuideName());
			profitManager.createTouristGroupProfit(profit);
		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			reward = (TouristGroupReward) ObjectHelper.objToObj(vo,
					TouristGroupReward.class);

			reward.setTouristGroupDetailId(detailId);
			reward.setTouristGroupSn(group.getTouristGroupSn());
			reward.setGuideId(detail.getGuideId());
			reward.setGuideName(detail.getGuideName());
			rewardManager.createTouristGroupReward(reward, session);
		} catch (Exception e) {
			e.printStackTrace();
		}

		guide = (Guide) session.getAttribute(Constants.USER_KEY);
		AccLogManager.saveInsertAccLog(guide.getGuideId(), vo);
	}

	private int saveTouristDetail(TouristGroupDetail detail)
			throws AppErrorException {
		if (detail == null
				|| detail.getTouristGroupSn() == null
				|| detail.getTouristGroupSn().trim().length() <= 0
				|| ((detail.getGuideId() == null || detail.getGuideId() == 0) && detail
						.getGuideName() == null))
			throw new AppErrorException("请输入旅程信息");

		try {
			detail.setTouristGroupDetailId(baseDao
					.getAutoIncrementId(SqlMappedId.TOURIST_GROUP_DETAI));

			baseDao.insert(SqlMappedId.TOURIST_GROUP_DETAI + "."
					+ SqlMappedId.insert, detail);

			guideManager.updateGuideStatus(detail);
		} catch (TravelDbException e) {
			throw new AppErrorException("保存旅程信息失败!", e);
		}
		return detail.getTouristGroupDetailId();
	}

	private void updateTouristDetail(TouristGroupDetail detail)
			throws AppErrorException {
		if (detail == null
				|| detail.getTouristGroupSn() == null
				|| detail.getTouristGroupSn().trim().length() <= 0
				|| (null == detail.getTouristGroupDetailId() || detail
						.getTouristGroupDetailId() == 0))
			throw new AppErrorException("请输入旅程信息");

		try {
			baseDao.updateByPrimaryKeySelective(SqlMappedId.TOURIST_GROUP_DETAI
					+ "." + SqlMappedId.updateByPrimaryKeySelective, detail);

			guideManager.updateGuideStatus(detail);
		} catch (TravelDbException e) {
			throw new AppErrorException("修改旅程信息失败!", e);
		}
	}

	public PageResult selectStatisticsForPage(StatisticsVo vo)
			throws AppErrorException {
		if (vo == null)
			vo = new StatisticsVo();
		PageResult page = new PageResult();
		StatisticsExample example = ExampleFactory.createStatisticsExample();
		example.createCriteria(vo);

		try {
			page.setSelectDataMappedId(SqlMappedId.TOURIST_GROUP_DETAI + "."
					+ SqlMappedId.statisticsByPageExample);
			page.setCountMappedId(SqlMappedId.TOURIST_GROUP_DETAI + "."
					+ SqlMappedId.StatisticsCountByExample);
			page.setSqlParamObj(example);

			if (vo.getCurPage() == null)
				vo.setCurPage(1);
			else if (vo.getCurPage() != null && vo.getCurPage() <= 1)
				vo.setCurPage(1);

			page.setCurPage(vo.getCurPage());
			page.setPageSize(20);

			page = baseDao.selectByPage(page);
		} catch (TravelDbException e) {
			throw new AppErrorException("获取财务统计信息列表失败,请稍候重试!", e);
		}
		return page;
	}

	@SuppressWarnings("unchecked")
	public RewardProfit getRewardProfitByStatistics(StatisticsVo vo) {
		if (vo == null)
			vo = new StatisticsVo();
		StatisticsExample example = ExampleFactory.createStatisticsExample();
		example.createCriteria(vo);

		List<RewardProfit> profits;
		try {
			profits = (List<RewardProfit>) baseDao.selectByExample(
					SqlMappedId.TOURIST_GROUP_DETAI + "."
							+ SqlMappedId.StatisticsCount, example);
			if (profits != null && profits.size() > 0) {
				return profits.get(0);
			}
		} catch (TravelDbException e) {
			e.printStackTrace();
		}

		return null;
	}

	public PageResult selectTouristForPage(TouristDetailVo vo)
			throws AppErrorException {
		if (vo == null)
			vo = new TouristDetailVo();
		PageResult page = new PageResult();
		TouristWorkDetailExample workDetail = ExampleFactory
				.createTouristWorkDetailExample();
		workDetail.createCriteria(vo);

		if (vo.getOrderBy() == null || vo.getOrderBy().trim().length() <= 0)
			workDetail.setOrderByClause(" tgd_end_dt desc ");
		else {
			try {
				workDetail.setOrderByClause(ObjectHelper.getOrderBy(vo
						.getOrderBy(), vo.getACode() == null ? 0 : vo
						.getACode()));
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}

		try {
			page.setSelectDataMappedId(SqlMappedId.TOURIST_GROUP_DETAI + "."
					+ SqlMappedId.selectPageByExample);
			page.setCountMappedId(SqlMappedId.TOURIST_GROUP_DETAI + "."
					+ SqlMappedId.countByPageExample);
			page.setSqlParamObj(workDetail);

			if (vo.getCurPage() == null)
				vo.setCurPage(1);
			else if (vo.getCurPage() != null && vo.getCurPage() <= 1)
				vo.setCurPage(1);

			page.setCurPage(vo.getCurPage());
			page.setPageSize(20);

			page = baseDao.selectByPage(page);
		} catch (TravelDbException e) {
			throw new AppErrorException("获取导游数据列表失败,请稍候重试!", e);
		}

		return page;
	}

	public String deleteTourist(String detailIds, HttpSession session)
			throws AppErrorException {
		if (detailIds == null)
			throw new AppErrorException("请选择要进行删除的旅游团信息");

		Guide guide = (Guide)session.getAttribute(Constants.USER_KEY);
		if(guide.getGuideType()==null||guide.getGuideType()!=1){
			return "你没有此权限，请联系管理员开通此权限!";
		}
		
		String errorMess = "[";
		String succMess = "[";
		if (detailIds.indexOf(",") > 0) {
			for (String detailId : detailIds.split(",")) {
				try {
					this.deleteTouristById(Integer.parseInt(detailId), session);
					succMess += "(" + detailId + ")";
				} catch (NumberFormatException e) {
					errorMess += "(" + detailId + ")";
				} catch (AppErrorException e1) {
					errorMess += "(" + detailId + ")";
				}
			}
		} else {
			try {
				this.deleteTouristById(Integer.parseInt(detailIds), session);
				succMess += "(" + detailIds + ")";
			} catch (NumberFormatException e) {
				errorMess += "(" + detailIds + ")";
			} catch (AppErrorException e1) {
				errorMess += "(" + detailIds + ")";
			}
		}
		errorMess += "]";
		succMess += "]";

		return "【成功删除：" + succMess + "】"
				+ ("[]".equals(errorMess) ? "" : "【删除失败:" + errorMess + "】");
	}

	private void deleteTouristById(int detailId, HttpSession session)
			throws AppErrorException {
		TouristGroupDetail detail = new TouristGroupDetail();
		detail.setTouristGroupDetailId(detailId);
		try {
			detail = (TouristGroupDetail) baseDao.selectByPrimaryKey(
					SqlMappedId.TOURIST_GROUP_DETAI + "."
							+ SqlMappedId.selectByPrimaryKey, detail);
			if (detail == null)
				throw new AppErrorException("不存在此旅游团细节信息!");
		} catch (TravelDbException e1) {
			e1.printStackTrace();
			throw new AppErrorException("不存在此旅游团细节信息!", e1);
		}

		try {
			baseDao.getSqlMapClient().startTransaction();

			// 删除掉奖励信息
			TouristGroupRewardExample rwardExample = ExampleFactory
					.createTouristGroupRewardExample();
			rwardExample.createCriteria().andTgrTouristGroupDetailIdEqualTo(
					detail.getTouristGroupDetailId());
			baseDao.deleteByExample(SqlMappedId.TOURIST_GROUP_REWARD + "."
					+ SqlMappedId.deleteByExample, rwardExample);

			// 删除掉创利信息
			TouristGroupProfitExample profitExample = ExampleFactory
					.createTouristGroupProfitExample();
			profitExample.createCriteria().andTgpTouristGroupDetailIdEqualTo(
					detail.getTouristGroupDetailId());
			baseDao.deleteByExample(SqlMappedId.TOURIST_GROUP_PROFIT + "."
					+ SqlMappedId.deleteByExample, profitExample);

			try {// 删除掉旅游团基本信息
				String groupId = detail.getTouristGroupSn();
				TouristGroupDetailExample detailExample = ExampleFactory
						.createTouristGroupDetailExample();
				detailExample.createCriteria().andTgdTouristGroupSnEqualTo(
						groupId);
				if (baseDao.countByExample(SqlMappedId.TOURIST_GROUP_DETAI
						+ "." + SqlMappedId.countByExample, detailExample) == 1) {// 若只存在一个detail，则连同删除掉group
					TouristGroupExample groupExample = ExampleFactory
							.createTouristGroupExample();
					groupExample.createCriteria().andTouristGroupSnEqualTo(
							groupId);
					baseDao.deleteByExample(SqlMappedId.TOURIST_GROUP + "."
							+ SqlMappedId.deleteByExample, groupExample);
				}
			} catch (TravelDbException e) {
				e.printStackTrace();
			}

			// 删除掉细节信息
			baseDao.deleteByPrimaryKey(SqlMappedId.TOURIST_GROUP_DETAI + "."
					+ SqlMappedId.deleteByPrimaryKey, detail);

			baseDao.getSqlMapClient().commitTransaction();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				baseDao.getSqlMapClient().endTransaction();
			} catch (TravelDbException e) {
				e.printStackTrace();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

		Guide guide = (Guide) session.getAttribute(Constants.USER_KEY);
		AccLogManager.saveDeleteAccLog(guide.getGuideId(), detail);
	}
	
	@SuppressWarnings("unchecked")
	public final int countGuideGroupNum(final int guideId, GuideVO gVo){
		StatisticsVo vo = new StatisticsVo();
		StatisticsExample example = ExampleFactory.createStatisticsExample();
		
		vo.setSearchCode(Constants.SEARCH_GUIDE_ID_CODE);
		vo.setSearchKeyword(guideId+"");
		
		if(null!=gVo.getStartDate()){
			Date thisDay = DateHelper.parseToDate(gVo.getStartDate(), DateHelper.yyyyMMdd);
			if(null!=thisDay){
				vo.setDateCode(Constants.DATETYPE_GROUP_START_DATE_CODE);
				vo.setStDate(DateHelper.getThisMonthFirstDay(thisDay));
				vo.setEdDate(DateHelper.getThisMonthEndDay(thisDay));
			}
		}else{
			vo.setDateCode(Constants.DATETYPE_GROUP_START_DATE_CODE);
			vo.setStDate(DateHelper.getMonthFirstDay());
			vo.setEdDate(DateHelper.getMonthEndDay());
		}
		
		example.createCriteria(vo);

		try {
			 List<RewardProfit> datas = null;
			 
			 if(gVo.getComplete()){
				 datas = (List<RewardProfit>) baseDao.selectByExample(SqlMappedId.TOURIST_GROUP_DETAI + "."
							+ SqlMappedId.StatisticsCount, example);
			 }else{
			     datas = (List<RewardProfit>) baseDao.selectByExample(SqlMappedId.TOURIST_GROUP_DETAI + "."
					        + SqlMappedId.StatisticsUnCompleteCount, example);
			 }
			 
			if (null == datas || datas.size() <= 0)
				return 0;
			else if (null != datas.get(0)
					&& null != datas.get(0).getTotalGroupNum())
				return datas.get(0).getTotalGroupNum();
			 
			 
		} catch (TravelDbException e) {
			e.printStackTrace();
		}
		return 0;
	}

	public final String getLastTouristTime(final int guideId) {
		TouristDetailVo vo = new TouristDetailVo();
		vo.setSearchCode(Constants.SEARCH_GUIDE_ID_CODE);
		vo.setSearchKeyword(guideId+"");
		try {
			PageResult details = (PageResult) this.selectTouristForPage(vo);
			if (details == null || details.getPageList() == null || details.getPageList().size() <= 0)
				return "";
			else {
				TouristWorkDetail detail = (TouristWorkDetail) details.getPageList().get(0);
				guideManager.updateGuideStatus(guideId, detail.getStartDt(), detail.getEndDt());
				return "("+detail.getStartDt() + "~" + detail.getEndDt()+")";
			}
		} catch (AppErrorException e) {
			e.printStackTrace();
		}
		return "";
	}
	
	public void updateTourist(TouristDetailVo vo, HttpSession session)
			throws AppErrorException {
		if (null == vo)
			throw new AppErrorException("请输入旅游团详细信息!");
		TouristGroupDetail detail = null;
		TouristGroup group = null;
		TouristGroupProfit profit = null;
		TouristGroupReward reward = null;

		try {
			detail = (TouristGroupDetail) ObjectHelper.objToObj(vo,
					TouristGroupDetail.class);
			group = (TouristGroup) ObjectHelper
					.objToObj(vo, TouristGroup.class);

			Date startDate = null, endDate = null;
			if (null != vo.getStDate()) {
				try {
					startDate = DateHelper.parseToDate(vo.getStDate(),
							DateHelper.yyyyMMdd);
					if (null == vo.getEdDate())
						endDate = new Date();
					else
						endDate = DateHelper.parseToDate(vo.getEdDate(),
								DateHelper.yyyyMMdd);

					detail.setStartDt(startDate);
					detail.setContinuedDate(new Float(DateHelper
							.getDaysBetween(startDate, endDate)));
					detail.setEndDt(endDate);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		}

		try {// 先保存旅行团信息
			baseDao.getSqlMapClient().startTransaction();
			group.setTouristGroupId(groupManager.getTouristGroupBySn(group
					.getTouristGroupSn()));
			groupManager.updateTouristGroup(group);
			updateTouristDetail(detail);

			if (null != group.getTouristFile()
					&& group.getTouristFile().trim().length() > 0)
				FileHelper.CopyFileByChannel(group.getTouristFile(),
						Constants.FILE_SAVE_DIR + group.getTouristGroupSn()
								+ "_" + detail.getTouristGroupDetailId());
			baseDao.getSqlMapClient().commitTransaction();
		} catch (SQLException e) {
			e.printStackTrace();
			// throw new AppErrorException("增加旅程信息失败! 请检查必填数据是否已填完整!");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				baseDao.getSqlMapClient().endTransaction();
			} catch (SQLException e) {
				e.printStackTrace();
				throw new AppErrorException("增加旅程信息失败! 请检查必填数据是否已填完整!");
			}
		}

		try {// 再保存旅行团创利和奖励信息
			profit = (TouristGroupProfit) ObjectHelper.objToObj(vo,
					TouristGroupProfit.class);
			profitManager.updateTouristGroupProfit(profit);
		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			reward = (TouristGroupReward) ObjectHelper.objToObj(vo,
					TouristGroupReward.class);
			rewardManager.updateTouristGroupReward(reward, session);
		} catch (Exception e) {
			e.printStackTrace();
		}

		Guide guide = (Guide) session.getAttribute(Constants.USER_KEY);
		AccLogManager.saveUpdateAccLog(guide.getGuideId(), vo);
	}

	/**
	 * 导入Excel文件
	 * 
	 * @param excelFile
	 * @throws AppErrorException
	 */
	public void inportTourist(String excelFile, HttpSession session)
			throws AppErrorException {
		FileImport fileImport = new ExcelImportor();
		List<Map<String, Object>> dataList = fileImport.importData(excelFile);
		RandomNumberHelper ranHelper = new RandomNumberHelper();
		for (Map<String, Object> data : dataList) {
			try {
				TouristDetailVo vo = (TouristDetailVo) ObjectHelper.mapToObj(
						data, TouristDetailVo.class);
				vo.setTouristGroupSn(ranHelper.getPk());
				createTourist(vo, session);
			} catch (Exception e) {
				e.printStackTrace();
				continue;
			}
		}
	}
}
